/**
 * 
 */

var ColorPicker = new Class(
{
	initialize: function(input, options)
	{
		// options
		this.options = Object.extend({
			'imgBase': '/img/colorpicker/',
			'colorNames': {'aliceblue':'F0F8FF','darkslategray':'2F4F4F','lightsalmon':'FFA07A','palevioletred':'DB7093','antiquewhite':'FAEBD7','darkturquoise':'00CED1','lightseagreen':'20B2AA','papayawhip':'FFEFD5','aqua':'00FFFF','darkviolet':'9400D3','lightskyblue':'87CEFA','peachpuff':'FFDAB9','aquamarine':'7FFFD4','deeppink':'FF1493','lightslategray':'778899','peru':'CD853F','azure':'F0FFFF','deepskyblue':'00BFFF','lightsteelblue':'B0C4DE','pink':'FFC0CB','beige':'F5F5DC','dimgray':'696969','lightyellow':'FFFFE0','plum':'DDA0DD','bisque':'FFE4C4','dodgerblue':'1E90FF','lime':'00FF00','powderblue':'B0E0E6','black':'000000','firebrick':'B22222','limegreen':'32CD32','purple':'800080','blanchedalmond':'FFEBCD','floralwhite':'FFFAF0','linen':'FAF0E6','red':'FF0000','blue':'0000FF','forestgreen':'228B22','magenta':'FF00FF','rosybrown':'BC8F8F','blueviolet':'8A2BE2','fuchsia':'FF00FF','maroon':'800000','royalblue':'4169E1','brown':'A52A2A','gainsboro':'DCDCDC','mediumaquamarine':'66CDAA','saddlebrown':'8B4513','burlywood':'DEB887','ghostwhite':'F8F8FF','mediumblue':'0000CD','salmon':'FA8072','cadetblue':'5F9EA0','gold':'FFD700','mediumorchid':'BA55D3','sandybrown':'F4A460','chartreuse':'7FFF00','goldenrod':'DAA520','mediumpurple':'9370DB','seagreen':'2E8B57','chocolate':'D2691E','gray':'808080','mediumseagreen':'3CB371','seashell':'FFF5EE','coral':'FF7F50','green':'008000','mediumslateblue':'7B68EE','sienna':'A0522D','cornflowerblue':'6495ED','greenyellow':'ADFF2F','mediumspringgreen':'00FA9A','silver':'C0C0C0','cornsilk':'FFF8DC','honeydew':'F0FFF0','mediumturquoise':'48D1CC','skyblue':'87CEEB','crimson':'DC143C','hotpink':'FF69B4','mediumvioletred':'C71585','slateblue':'6A5ACD','cyan':'00FFFF','indianred':'CD5C5C','midnightblue':'191970','slategray':'708090','darkblue':'00008B','indigo':'4B0082','mintcream':'F5FFFA','snow':'FFFAFA','darkcyan':'008B8B','ivory':'FFFFF0','mistyrose':'FFE4E1','springgreen':'00FF7F','darkgoldenrod':'B8860B','khaki':'F0E68C','moccasin':'FFE4B5','steelblue':'4682B4','darkgray':'A9A9A9','lavender':'E6E6FA','navajowhite':'FFDEAD','tan':'D2B48C','darkgreen':'006400','lavenderblush':'FFF0F5','navy':'000080','teal':'008080','darkkhaki':'BDB76B','lawngreen':'7CFC00','oldlace':'FDF5E6','thistle':'D8BFD8','darkmagenta':'8B008B','lemonchiffon':'FFFACD','olive':'808000','tomato':'FD6347','darkolivegreen':'556B2F','lightblue':'ADD8E6','olivedrab':'6B8E23','turquoise':'40E0D0','darkorange':'FF8C00','lightcoral':'F08080','orange':'FFA500','violet':'EE82EE','darkorchid':'9932CC','lightcyan':'E0FFFF','orangered':'FF4500','wheat':'F5DEB3','darkred':'8B0000','lightgoldenrodyellow':'FAFAD2','orchid':'DA70D6','white':'FFFFFF','darksalmon':'E9967A','lightgreen':'90EE90','palegoldenrod':'EEE8AA','whitesmoke':'F5F5F5','darkseagreen':'8FBC8F','lightgrey':'D3D3D3','palegreen':'98FB98','yellow':'FFFF00','darkslateblue':'483D8B','lightpink':'FFB6C1','paleturquoise':'AFEEEE','yellowgreen':'9ACD32'}
		}, options || {});
		
		// related input & events
		this.input = $(input);
		this.input.addEvent('focus',    this.show.bind(this));
//		document.body.addEvent('click', this.hide.bind(this));
//		this.input.addEvent('click',    this.show.bind(this));
		
		// default color
		//this.baseColor = this.input.value || $RGB(255, 0, 0);
	},
	
	show: function(evt)
	{
		if (!this.sticky)
		{
			// creates picker
			this.create();
			
			// elements
			this.largeGradient    = $E('img[name=cp_largeGradient]', this.cp);
			this.verticalGradient = $E('div.cp_verticalGradient', this.cp);
			this.selectedColor    = $E('div.cp_currentColorBg', this.cp);
			this.previousColor    = $E('div.cp_previousColorBg', this.cp);
			this.colorR           = $E('input[name=colorR]', this.cp);
			this.colorG           = $E('input[name=colorG]', this.cp);
			this.colorB           = $E('input[name=colorB]', this.cp);
			
			this.previousColor.addEvent('click', this.setColor.pass(this.baseColor, this));
			
			this.colorR.addEvent('change', this.onColorChange.bind(this));
			this.colorG.addEvent('change', this.onColorChange.bind(this));
			this.colorB.addEvent('change', this.onColorChange.bind(this));
			
			// events
			this.largeGradient.addEvent('mousedown', this.onLargeGradient.bindWithEvent(this));
			this.verticalGradient.addEvent('mousedown', this.onVerticalGradient.bindWithEvent(this));
		}
		
		// resets color
		this.baseColor = this.input.value || $RGB(255, 0, 0);
		this.previousColor.setStyle('background', '' + this.baseColor);
		this.setColor(this.baseColor);
		
		// displays picker
		this.sticky.show();
		
//		new Event(evt).stop();
	},
	
	hide: function()
	{
		if (this.sticky)
			this.sticky.hide();
	},
	
	create: function()
	{
		// the color picker
		this.cp = new DOM('div', {'class': 'cp_colorPickerContent'});
		this.cp.innerHTML =
			'<div class="cp_largeGradient gradient">' +
				'<img src="' + this.options.imgBase + 'gradient_overlay.png" name="cp_largeGradient" />' +
			'</div>' +
			'<div class="cp_verticalGradient gradient">' +
				'<img src="' + this.options.imgBase + 'vertical_gradient.png" name="cp_verticalGradient" />' +
				'<img src="' + this.options.imgBase + 'vertical_gradient_arrows.gif" name="cp_verticalGradientArrows" class="arrows" />' +
			'</div>' +
			'<div class="cp_selectedColor">' +
				'<div class="cp_currentColorBg"></div>' +
				'<div class="cp_previousColorBg"></div>' +
				'<img src="' + this.options.imgBase + 'web_safe.gif" class="cp_webSafe" title="Click to select Web Safe color" />' +
				'<div class="cp_rgbInputs">' +
					'<label for="colorR">R:</label>' +
					'<input type="text" name="colorR" maxlength="3" size="3" />' +
					'<br />' +
					'<label for="colorR">G:</label>' +
					'<input type="text" name="colorG" maxlength="3" size="3" />' +
					'<br />' +
					'<label for="colorR">B:</label>' +
					'<input type="text" name="colorB" maxlength="3" size="3" />' +
					'<br />' +
				'</div>' +
				'<div class="cp_buttons">' +
					'<button class="ok">OK</button><br />' +
					'<button class="cancel">Cancel</button>' +
				'</div>' +
			'</div>';
		
		// the sticked window
		this.sticky = new Window.Sticky(this.input).setContent(this.cp);
		this.sticky.window.addClass('cp_colorPicker');
		
		// events
		$E('button.ok', this.cp).addEvent('click', this.onValidate.bind(this));
		$E('button.cancel', this.cp).addEvent('click', this.hide.bind(this));
//		this.cp.addEvent('click', function(evt) { new Event(evt).stop(); });
	},
	
	setColor: function(color, ignoreLargeGradient)
	{
		color = new Color(color);
		this.currentColor = color;
		
		if (!ignoreLargeGradient)
		{
			this.largeGradientColor = color;
			this.largeGradient.getParent().setStyle('background', color);
		}
		this.selectedColor.setStyle('background', color);
		
		this.colorR.value = color[0];
		this.colorG.value = color[1];
		this.colorB.value = color[2];
	},
	
	// callbacks
	
	onColorChange: function()
	{
		this.setColor([ this.colorR.value, this.colorG.value, this.colorB.value ]);
	},
	
	onValidate: function()
	{
		this.input.value = this.currentColor;
		this.hide();
	},
	
	onLargeGradient: function(evt)
	{
		var p = this.largeGradient.getPosition();
		var color = this.getLargeGradientColor(evt.page.x - p.x, evt.page.y - p.y, this.largeGradientColor);
		this.setColor(color, true);
		evt.stop();
	},
	
	onVerticalGradient: function(evt)
	{
		var p = this.verticalGradient.getPosition();
		var color = this.getVerticalGradientColor(evt.page.y - p.y, 256);
		this.setColor(color);
		evt.stop();
	},
	
	// maths for gradients
	
	getLargeGradientColor: function(x, y, Base)
	{
		// x and y must be between 0 and 255
		x = Math.min(255, Math.max(0, x));
		y = Math.min(255, Math.max(0, y));
		
		var r = Math.round((1 -(1 - (Base[0] / 255)) * (x / 255)) * (255 - y));
		var g = Math.round((1 -(1 - (Base[1] / 255)) * (x / 255)) * (255 - y));
		var b = Math.round((1 -(1 - (Base[2] / 255)) * (x / 255)) * (255 - y));
		
		return [ r, g, b ];
	},
	
	getVerticalGradientColor: function(i, sZ)
	{
		// i must be between 0 and 255
		i = Math.min(255, Math.max(0, i));
		
		var n = sZ/6;
		var j = sZ/n;
		var C = i;
		var c = C % n;
		
		var r = Math.round((C < n) ? 255 : (C < n * 2) ? 255 - c * j : (C < n * 4) ? 0 : (C < n * 5) ? c * j : 255);
		var g = Math.round((C < n * 2) ? 0 : (C < n * 3) ? c * j : (C < n * 5) ? 255 : 255 - c * j);
		var b = Math.round((C < n) ? c * j : (C < n * 3) ? 255 : (C < n * 4) ? 255 - c * j : 0);
		
		return [ r, g, b ];
	}
});

Window.onDomReady(function() {
	$ES('input.color').each(function(input) { new ColorPicker(input); });
});